package org.jpass.dc.view.project;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.json.annotations.JSON;
import org.apache.tools.ant.BuildException;
import org.jpass.dc.business.conpiler.BuildMessage;
import org.jpass.dc.business.project.bean.CProject;
import org.jpass.dc.business.project.logic.ProjectService;
import org.jpass.dc.business.user.bean.UserVOBean;
import org.jpass.dc.common.exception.ApplicationException;
import org.jpass.dc.common.exception.IDEBuildException;
import org.jpass.dc.common.util.StringUtil;
import org.jpass.dc.view.common.BasicAction;

import com.opensymphony.xwork2.Action;

public class ProjectAction extends BasicAction {
	
	private static final long serialVersionUID = -6153546947133093627L;
	
	private Log log = LogFactory.getLog(getClass());
	
	private CProject cProject = new CProject();
	
	private ProjectService projectService = new ProjectService();
	
	private String mainFile;
	
	private String ids;
	
	/* 返回给客户端，表示请求是否成功 */
	private boolean success = true;
	
	/* 发回给客户端的提示信息 */
	private String msg;
	
	/* 发回给客户端的提示信息的类型 */
	private String type;

	public String create() {
		
		msg = validateProjectInfo();
		if (msg != null) {
			type = "WARNG";
			success = false;
		} else {
			UserVOBean user = this.getCurrentUser();
			cProject.setProjectName(cProject.getProjectName().trim());
			cProject.setProjectType(cProject.getProjectType().trim());
			cProject.setUser(user);
			cProject.setCreatedDate(new Date());
			cProject.setStatus(true);
			try {
				projectService.create(cProject, this.getUserRealWrokRootPath());
			} catch (ApplicationException ae) {
				msg = ae.getMessage();
				type = "ERROR";
				success = false;
			} catch (Exception e) {
				msg = "Fail to create project.";
				type = "ERROR";
				success = false;
				log.error(user.getEmail() + "创建项目时发生异常，异常信息：", e);
			}
			
		}
		return Action.SUCCESS;
	}
	
	public String open() {
		if (!StringUtil.isBlank(ids)) {
			boolean bool = projectService.updateProjectStatus(this.getCurrentUser().getId(), ids.split(","), true);
			if (bool) {
				msg = "Successful!";
				type = "";
				success = true;
			} else {
				msg = "Faild!";
				type = "error";
				success = false;
			}
		} else {
			msg = "Please select the project that you want to open.";
			type = "warng";
			success = true;
		}
		
		return Action.SUCCESS;
	}
	
	public String close() {
		if (!StringUtil.isBlank(cProject.getProjectName())) {
			UserVOBean user = this.getCurrentUser();
			CProject p = projectService.findByUserIdAndProjectName(user.getId(), cProject.getProjectName());
			if (p != null) {
				boolean bool = projectService.updateProjectStatus(this.getCurrentUser().getId(), new String[] {p.getId()}, false);
				if (bool) {
					msg = "Successful!";
					type = "";
					success = true;
				} else {
					msg = "Project '" + cProject.getProjectName()  + "' faild to close!";
					type = "error";
					success = false;
				}
			} else {
				msg = "Prease select a project.";
				type = "warng";
				success = false;
			}
		}
		
		return Action.SUCCESS;
	}
	
	public String build() {
		try {
			long startTime = System.currentTimeMillis();   //获取开始时间  
			projectService.build(this.getWebAppRealPath(), this.getUserRealWrokRootPath(), cProject.getProjectName());
			long endTime = System.currentTimeMillis(); //获取结束时间 
			double totalTime = (endTime - startTime) / 1000.0;
			msg = "build successful" + "\n" + "Total time: " + String.valueOf(totalTime) + " seconds";
			type = "build_successful";
			success = true;
		} catch (IDEBuildException e) {
			String errorMsg = new BuildMessage(
					this.getUserRealWrokRootPath() + "/error.log").getErrorMessage();
			msg = e.getMessage() + "\n" + errorMsg;
			type = "compile_failed";
			success = false;
		}
		
		return Action.SUCCESS;
	}
	
	public String run() {
		try {
			projectService.run(this.getWebAppRealPath(), this.getUserRealWrokRootPath(), cProject.getProjectName(), mainFile);
			msg = new BuildMessage(
					this.getUserRealWrokRootPath() + "/out.log").getErrorMessage();
			success = true;
		} catch (BuildException e) {
			String errorMsg = new BuildMessage(
					this.getUserRealWrokRootPath() + "/error.log").getErrorMessage();
			msg = e.getMessage() + "\n" + errorMsg;
			type = "compile_failed";
			success = false;
		}
		
		return Action.SUCCESS;
	}
	
	/**
	 * 验证客户端传过来的数据
	 * @return
	 */
	public String validateProjectInfo() {
		String projectName = cProject.getProjectName();
		String projectType = cProject.getProjectType();
		if (StringUtil.isBlank(projectName)) {
			return "The project name cannot be empty.";
		}else if (StringUtil.getByteLength(projectName.trim()) > 255) {
			return "The length of the project name cannot be more than 255.";
		}/*else if (projectName.matches("^[^/\\\\<>\\*\\?:\"\\|\\.]*[^/\\\\<>\\*\\?:\"\\|\\.]$")) { // API 所支持的元字符有：([{\^-$|}])?*+.
			//^[^\/\\<>\*\?\:"\|\.]*[^\/\\<>\*\?\:"\|\.]$
			return "The project name cannot contain /\\<>*?:\"|.";
		}*/
		if (StringUtil.isBlank(projectType)) {
			return "The project type cannot be empty.";
		}else if (projectType.matches("[java|c|c++|php]")) {
			return "The project type must be java,c,c++ or php.";
		}
		
		return null;
	}
	
	@JSON(serialize = false)
	public String getMainFile() {
		return mainFile;
	}

	public void setMainFile(String mainFile) {
		this.mainFile = mainFile;
	}

	@JSON(serialize = false)
	public String getIds() {
		return ids;
	}

	public void setIds(String ids) {
		this.ids = ids;
	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@JSON(serialize = false)
	public CProject getCProject() {
		return cProject;
	}

	public void setCProject(CProject cProject) {
		this.cProject = cProject;
	}
}
